En omfattande guide till JavaScripts BigInt-typ, som tÀcker dess funktioner, anvÀndning och tillÀmpningar för att hantera aritmetik med stora heltal. LÀr dig övervinna JavaScripts begrÀnsningar och utföra komplexa berÀkningar med precision.
JavaScript BigInt: BemÀstra aritmetik med stora heltal
JavaScript, trots att det Ă€r ett mĂ„ngsidigt sprĂ„k, har begrĂ€nsningar nĂ€r det gĂ€ller att hantera mycket stora heltal. Standardtypen `Number` kan endast representera heltal korrekt upp till en viss grĂ€ns, kĂ€nd som `Number.MAX_SAFE_INTEGER`. Ăver denna grĂ€ns blir berĂ€kningar oprecisa, vilket leder till ovĂ€ntade resultat. Det Ă€r hĂ€r BigInt
kommer till undsÀttning. Introducerat i ECMAScript 2020 Àr BigInt
ett inbyggt objekt som ger ett sÀtt att representera och manipulera heltal av godtycklig storlek, vilket övertrÀffar begrÀnsningarna hos standardtypen `Number`.
FörstÄ behovet av BigInt
Innan BigInt
var JavaScript-utvecklare tvungna att förlita sig pÄ bibliotek eller anpassade implementeringar för att hantera berÀkningar med stora heltal. Dessa lösningar medförde ofta prestandakostnader och ökad komplexitet. Införandet av BigInt
gav ett inbyggt och effektivt sÀtt att arbeta med stora heltal, vilket öppnade upp möjligheter för tillÀmpningar inom olika omrÄden, inklusive:
- Kryptografi: Att sÀkert hantera stora primtal Àr avgörande för kryptografiska algoritmer.
- Finansiella berÀkningar: Att noggrant representera stora penningvÀrden utan precisionsförlust.
- Vetenskapliga berÀkningar: Att utföra komplexa berÀkningar som involverar extremt stora eller smÄ tal.
- TidsstÀmplar med hög precision: Att representera tidsstÀmplar med nanosekundprecision.
- ID-generering: Att skapa unika och mycket stora identifierare.
Skapa BigInt-vÀrden
Det finns tvÄ primÀra sÀtt att skapa BigInt
-vÀrden i JavaScript:
- AnvÀnda `BigInt()`-konstruktorn: Denna konstruktor kan konvertera ett tal, en strÀng eller ett booleskt vÀrde till en
BigInt
. - AnvÀnda suffixet `n`: Att lÀgga till `n` i slutet av en heltalsliteral skapar en
BigInt
.
Exempel:
AnvÀnda `BigInt()`-konstruktorn:
const bigIntFromNumber = BigInt(12345678901234567890);
const bigIntFromString = BigInt("98765432109876543210");
const bigIntFromBoolean = BigInt(true); // Resulterar i 1n
const bigIntFromFalseBoolean = BigInt(false); // Resulterar i 0n
console.log(bigIntFromNumber); // Utskrift: 12345678901234567890n
console.log(bigIntFromString); // Utskrift: 98765432109876543210n
console.log(bigIntFromBoolean); // Utskrift: 1n
console.log(bigIntFromFalseBoolean); // Utskrift: 0n
AnvÀnda suffixet `n`:
const bigIntLiteral = 12345678901234567890n;
console.log(bigIntLiteral); // Utskrift: 12345678901234567890n
Viktigt att notera: Du kan inte direkt blanda BigInt
- och Number
-vÀrden i aritmetiska operationer. Du mÄste explicit konvertera dem till samma typ innan du utför berÀkningar. Ett försök att blanda dem direkt kommer att resultera i ett `TypeError`.
Aritmetiska operationer med BigInt
BigInt
stöder de flesta av de vanliga aritmetiska operatorerna, inklusive:
- Addition (`+`)
- Subtraktion (`-`)
- Multiplikation (`*`)
- Division (`/`)
- Rest (`%`)
- Exponentiering (`**`)
Exempel:
const a = 12345678901234567890n;
const b = 98765432109876543210n;
const sum = a + b;
const difference = a - b;
const product = a * b;
const quotient = a / 2n; // Notera: Division avrundar mot noll
const remainder = a % 7n;
const power = a ** 3n; // Exponentiering fungerar som förvÀntat
console.log("Summa:", sum); // Utskrift: Summa: 111111111011111111100n
console.log("Differens:", difference); // Utskrift: Differens: -86419753208641975320n
console.log("Produkt:", product); // Utskrift: Produkt: 1219326311370217957951669538098765432100n
console.log("Kvot:", quotient); // Utskrift: Kvot: 6172839450617283945n
console.log("Rest:", remainder); // Utskrift: Rest: 5n
console.log("Potens:", power); // Utskrift: Potens: 187641281029182300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000n
Viktiga övervÀganden:
- Division: Division med
BigInt
-vÀrden avrundar mot noll. Detta innebÀr att decimaldelen av resultatet kastas bort. Om du behöver mer exakt division, övervÀg att anvÀnda bibliotek som stöder aritmetik med godtycklig precision. - UnÀr plusoperator (+): Den unÀra plusoperatorn (+) kan inte anvÀndas med
BigInt
-vÀrden eftersom det skulle krocka med Àldre asm.js-kod. AnvÀnd konverteringsfunktionen `Number()` för att konvertera en BigInt till ett Number om du behöver en numerisk representation (med förstÄelsen att du kan förlora precision). - Bitvisa operatorer:
BigInt
stöder ocksÄ bitvisa operatorer som `&`, `|`, `^`, `~`, `<<` och `>>`. Dessa operatorer fungerar som förvÀntat pÄ den binÀra representationen avBigInt
-vÀrdena.
JÀmförelseoperatorer
Du kan anvÀnda standardjÀmförelseoperatorer (`==`, `!=`, `<`, `>`, `<=`, `>=`) för att jÀmföra BigInt
-vÀrden med andra BigInt
-vÀrden eller till och med med Number
-vÀrden. Var dock medveten om risken för typomvandling (type coercion).
Exempel:
const a = 10n;
const b = 20n;
const c = 10;
console.log(a == b); // Utskrift: false
console.log(a != b); // Utskrift: true
console.log(a < b); // Utskrift: true
console.log(a > b); // Utskrift: false
console.log(a <= b); // Utskrift: true
console.log(a >= b); // Utskrift: false
console.log(a == c); // Utskrift: true (typomvandling)
console.log(a === c); // Utskrift: false (ingen typomvandling)
BÀsta praxis: AnvÀnd strikt likhet (`===`) och strikt olikhet (`!==`) för att undvika ovÀntad typomvandling nÀr du jÀmför BigInt
- och Number
-vÀrden.
Konvertera mellan BigInt och Number
Ăven om direkta aritmetiska operationer mellan BigInt
och Number
inte Àr tillÄtna, kan du konvertera mellan de tvÄ typerna. Var dock medveten om den potentiella risken för precisionsförlust nÀr du konverterar en BigInt
till en Number
om BigInt
-vÀrdet överstiger `Number.MAX_SAFE_INTEGER`.
Exempel:
const bigIntValue = 9007199254740991n; // Number.MAX_SAFE_INTEGER
const numberValue = Number(bigIntValue); // Konverterar BigInt till Number
console.log(numberValue); // Utskrift: 9007199254740991
const largerBigIntValue = 9007199254740992n; // Ăverstiger Number.MAX_SAFE_INTEGER
const largerNumberValue = Number(largerBigIntValue);
console.log(largerNumberValue); // Utskrift: 9007199254740992 (kan vara oprecis)
const numberToBigInt = BigInt(12345); // Konverterar Number till BigInt
console.log(numberToBigInt); // Utskrift: 12345n
AnvÀndningsfall och exempel
Kryptografi
Kryptografiska algoritmer förlitar sig ofta pÄ mycket stora primtal för sÀkerhet. BigInt
ger ett sÀtt att representera och manipulera dessa tal effektivt.
// Exempel: Generera ett enkelt (osÀkert) nyckelpar
function generateKeyPair() {
const p = 281n; // Ett primtal
const q = 283n; // Ett annat primtal
const n = p * q; // Modulus
const totient = (p - 1n) * (q - 1n); // Eulers totientfunktion
// VÀlj ett e (offentlig exponent) sÄ att 1 < e < totient och gcd(e, totient) = 1
const e = 17n;
// BerÀkna d (privat exponent) sÄ att (d * e) % totient = 1
let d = 0n;
for (let i = 1n; i < totient; i++) {
if ((i * e) % totient === 1n) {
d = i;
break;
}
}
return {
publicKey: { n, e },
privateKey: { n, d },
};
}
const keyPair = generateKeyPair();
console.log("Offentlig nyckel:", keyPair.publicKey);
console.log("Privat nyckel:", keyPair.privateKey);
Notera: Detta Àr ett förenklat exempel endast i demonstrationssyfte. Verklig kryptografi anvÀnder mycket större primtal och mer sofistikerade algoritmer.
Finansiella berÀkningar
NÀr man hanterar stora summor pengar, sÀrskilt i internationella transaktioner, Àr precision avgörande. BigInt
kan förhindra avrundningsfel och sÀkerstÀlla exakta berÀkningar.
// Exempel: BerÀkna rÀnta-pÄ-rÀnta
function calculateCompoundInterest(principal, rate, time) {
const principalBigInt = BigInt(principal * 100); // Konvertera till cent
const rateBigInt = BigInt(rate * 10000); // Konvertera till tiotusendelar av en procent
const timeBigInt = BigInt(time);
let amount = principalBigInt;
for (let i = 0n; i < timeBigInt; i++) {
amount = amount * (10000n + rateBigInt) / 10000n;
}
const amountInDollars = Number(amount) / 100;
return amountInDollars;
}
const principal = 1000000; // $1,000,000
const rate = 0.05; // 5% rÀnta
const time = 10; // 10 Är
const finalAmount = calculateCompoundInterest(principal, rate, time);
console.log("Slutligt belopp:", finalAmount); // Utskrift: Slutligt belopp: 1628894.6267774413 (ungefÀr)
I detta exempel konverterar vi kapitalbeloppet och rÀntan till BigInt
-vÀrden för att undvika avrundningsfel under berÀkningen. Resultatet konverteras sedan tillbaka till ett Number
för visning.
Arbeta med stora ID:n
I distribuerade system kan det vara en utmaning att generera unika ID:n över flera servrar. Genom att anvÀnda BigInt
kan du skapa mycket stora ID:n som sannolikt inte kommer att kollidera.
// Exempel: Generera ett unikt ID baserat pÄ tidsstÀmpel och server-ID
function generateUniqueId(serverId) {
const timestamp = BigInt(Date.now());
const serverIdBigInt = BigInt(serverId);
const random = BigInt(Math.floor(Math.random() * 1000)); // LÀgg till lite slumpmÀssighet
// Kombinera vÀrdena för att skapa ett unikt ID
const uniqueId = (timestamp << 20n) + (serverIdBigInt << 10n) + random;
return uniqueId.toString(); // Returnera som en strÀng för enkel hantering
}
const serverId = 123; // Exempel pÄ server-ID
const id1 = generateUniqueId(serverId);
const id2 = generateUniqueId(serverId);
console.log("Unikt ID 1:", id1);
console.log("Unikt ID 2:", id2);
BigInt och JSON
BigInt
-vÀrden stöds inte inbyggt av JSON. Ett försök att serialisera ett JavaScript-objekt som innehÄller en BigInt
med `JSON.stringify()` kommer att resultera i ett `TypeError`. För att hantera BigInt
-vÀrden nÀr du arbetar med JSON har du ett par alternativ:
- Konvertera till strÀng: Konvertera
BigInt
till en strÀng innan serialisering. Detta Àr den vanligaste och mest raka metoden. - Anpassad serialisering/deserialisering: AnvÀnd en anpassad funktion för serialisering och deserialisering för att hantera
BigInt
-vÀrden.
Exempel:
Konvertera till strÀng:
const data = {
id: 12345678901234567890n,
name: "Example Data",
};
// Konvertera BigInt till strÀng innan serialisering
data.id = data.id.toString();
const jsonData = JSON.stringify(data);
console.log(jsonData); // Utskrift: {"id":"12345678901234567890","name":"Example Data"}
// Vid deserialisering mÄste du konvertera strÀngen tillbaka till en BigInt
const parsedData = JSON.parse(jsonData, (key, value) => {
if (key === "id") {
return BigInt(value);
}
return value;
});
console.log(parsedData.id); // Utskrift: 12345678901234567890n
Anpassad serialisering/deserialisering (med `replacer` och `reviver`):
const data = {
id: 12345678901234567890n,
name: "Example Data",
};
// Anpassad serialisering
const jsonData = JSON.stringify(data, (key, value) => {
if (typeof value === 'bigint') {
return value.toString();
} else {
return value;
}
});
console.log(jsonData);
// Anpassad deserialisering
const parsedData = JSON.parse(jsonData, (key, value) => {
if (typeof value === 'string' && /^[0-9]+$/.test(value)) { // kontrollera om det Àr ett tal och en strÀng
try {
return BigInt(value);
} catch(e) {
return value;
}
}
return value;
});
console.log(parsedData.id);
WebblÀsarkompatibilitet
BigInt
har brett stöd i moderna webblÀsare. Det Àr dock viktigt att kontrollera kompatibiliteten för Àldre webblÀsare eller miljöer. Du kan anvÀnda ett verktyg som Can I use för att verifiera webblÀsarstöd. Om du behöver stödja Àldre webblÀsare kan du övervÀga att anvÀnda en polyfill, men var medveten om att polyfills kan pÄverka prestandan.
PrestandaövervÀganden
Ăven om BigInt
erbjuder ett kraftfullt sÀtt att arbeta med stora heltal, Àr det viktigt att vara medveten om potentiella prestandakonsekvenser.
BigInt
-operationer kan vara lÄngsammare Àn vanligaNumber
-operationer.- Konvertering mellan
BigInt
ochNumber
kan ocksÄ medföra en prestandakostnad.
AnvÀnd dÀrför BigInt
endast nÀr det Àr nödvÀndigt, och optimera din kod för prestanda om du utför ett stort antal BigInt
-operationer.
Slutsats
BigInt
Àr ett vÀrdefullt tillskott till JavaScript som gör det möjligt för utvecklare att hantera aritmetik med stora heltal med precision. Genom att förstÄ dess funktioner, begrÀnsningar och anvÀndningsfall kan du utnyttja BigInt
för att bygga robusta och exakta applikationer inom olika omrÄden, inklusive kryptografi, finansiella berÀkningar och vetenskaplig databehandling. Kom ihÄg att ta hÀnsyn till webblÀsarkompatibilitet och prestandakonsekvenser nÀr du anvÀnder BigInt
i dina projekt.
Vidare lÀsning
- Mozilla Developer Network (MDN) - BigInt
- V8 Blog - BigInt: Arbitrary-Precision Integers in JavaScript
Denna guide ger en omfattande översikt av BigInt
i JavaScript. Utforska de lÀnkade resurserna för mer djupgÄende information och avancerade tekniker.